package com.example.litehdfs.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 全局处理异常
 * @author mading
 *
 */
@ControllerAdvice
@RestController
public class GlobalErrorController extends AbstractErrorController{

    public GlobalErrorController(ErrorAttributes errorAttributes) {
      super(errorAttributes);
    }

    private static Logger log = LoggerFactory.getLogger(GlobalErrorController.class);
    
    @Autowired
    private ObjectMapper mapper;


    /**
     * 校验失败
     * @param e
     * @return
     */
    @ExceptionHandler(value = {BindException.class,MethodArgumentNotValidException.class,IllegalArgumentException.class})
    @ResponseBody
    public ResponseMsg<String> bindExceptionHandler(Exception e) {
        String msg = null;
        String field = null;
        if(e instanceof BindException){
            BindException e1 =  (BindException)e;
            msg = e1.getBindingResult().getFieldError().getDefaultMessage();
            field = e1.getBindingResult().getFieldError().getField();
        }else if(e instanceof MethodArgumentNotValidException){
            MethodArgumentNotValidException e1 = (MethodArgumentNotValidException)e;
            field = e1.getBindingResult().getFieldError().getField();
            msg = e1.getBindingResult().getFieldError().getDefaultMessage();
        }else if(e instanceof IllegalArgumentException){
        	IllegalArgumentException e1 = (IllegalArgumentException)e;
        	msg = e1.getMessage();
        }
        
        
        log.error("参数校验失败，field：{}，msg：{}" ,field,msg);
        log.error(e.getMessage(),e);
         
        return new ResponseMsg<>(CodeConstant.ERROR,msg+":"+field);
        
    }

    /**
     * 处理业务异常
     * @param e
     * @return
     */
    @ExceptionHandler(B2BServiceException.class)
	@ResponseBody
    public ResponseMsg<Object> serviceException(B2BServiceException e) {
	    String data = null;
        try {
          data = e.getData()!= null?mapper.writeValueAsString(e.getData()):null;
        } catch (JsonProcessingException e1) {
        	log.error(e1.getMessage(),e1);
        }
        
        log.error("异常信息： \n编号：{}\n消息：{}\n数据：{}\n位置：{}",
            e.getCode(),
            e.getMessage(),
            data,
            (e.getStackTrace()!=null && e.getStackTrace().length > 0)?e.getStackTrace()[0].toString():e.getStackTrace());
        
        return new ResponseMsg<>(e.getCode(),e.getMessage(),e.getData());
    }
    
	/**
	 * 未知异常处理
	 * @param e
	 * @return
	 */
	@ExceptionHandler(Exception.class)
	@ResponseBody
    public ResponseMsg<String> exception(Exception e) {
        log.error("未知错误",e);
        return new ResponseMsg<>(CodeConstant.ERROR,e.getMessage());
    }

    @RequestMapping("/error")
    public ResponseMsg<String> getErrorPathExec() {
    	return new ResponseMsg<>(CodeConstant.ERROR,"UNKOWN_URL");
    }

}
